package com.ky.pro.java.nio.http.server.outbound.client.impl.ok.http;

import com.ky.pro.java.nio.http.server.outbound.client.IGatewayClient;
import com.ky.pro.java.nio.http.server.utils.ResponseUtil;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.*;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

/**
 * @ClassName IGatewayClient
 * @Description IGatewayClient OK Http实现
 * @Date 2021/11/19 02:34
 * @Author kevin
 **/
public class OkHttpClientImpl implements IGatewayClient {

    OkHttpClient client;

    public OkHttpClientImpl() {
        // 超时时间可以通过外部配置实现，这里简单处理直接配置
        client = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .callTimeout(120, TimeUnit.SECONDS)
                .pingInterval(5, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .build();
    }

    @Override
    public HttpResponse sendRequest(FullHttpRequest request, InetSocketAddress endpointAddress) {

        String url = "http://" + endpointAddress.getHostString() + ":" + endpointAddress.getPort() + request.uri();

        Request.Builder okRequestBuilder = new Request.Builder()
                .url(url);

        // 处理请求Body
        int contentBytes = request.content().readableBytes();
        if (contentBytes > 0) {
            byte[] requestBodyBytes = new byte[contentBytes];
            request.content().getBytes(0, requestBodyBytes);
            okRequestBuilder.method(request.method().name(), RequestBody.create(requestBodyBytes));
        }

        // 处理请求头
        request.headers().forEach(header -> okRequestBuilder.addHeader(header.getKey(), header.getValue()));

        // 执行请求
        try (Response response = client.newCall(okRequestBuilder.build()).execute()) {
            return convertResponse(response, url);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseUtil.createResponseWithException(e);
        }

    }

    private HttpResponse convertResponse(Response response, String sourceUrl) throws IOException {

        String responseBody = response.body().string();
        System.out.println("Response from " + sourceUrl + ": \n" + responseBody);

        byte[] responseBytes = responseBody.getBytes("UTF-8");
        FullHttpResponse httpResponse = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(response.code()),
                Unpooled.wrappedBuffer(responseBytes));
        httpResponse.headers().set("Content-Type", response.header("Content-Type"));
        httpResponse.headers().setInt("Content-Length", responseBytes.length);

        return httpResponse;
    }
}
